package com.wuye.basic.service.impl;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

import cn.hutool.core.bean.BeanUtil;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.baomidou.mybatisplus.extension.toolkit.Db;
import com.github.pagehelper.PageInfo;
import com.wuye.basic.domain.*;
import com.wuye.basic.domain.dto.WyHomeDTO;
import com.wuye.basic.service.WyBalconyunithomeService;
import com.wuye.basic.service.WyHomeandtypeService;
import com.wuye.common.constant.HttpStatus;
import com.wuye.common.core.page.PageDomain;
import com.wuye.common.core.page.TableDataInfo;
import com.wuye.common.core.page.TableSupport;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import com.wuye.basic.mapper.WyHomeMapper;
import com.wuye.basic.service.IWyHomeService;

/**
 * 房间资料Service业务层处理
 * 
 * @author jack
 * @date 2024-11-26
 */
@Service
@RequiredArgsConstructor
public class WyHomeServiceImpl extends ServiceImpl<WyHomeMapper,WyHome>
        implements IWyHomeService
{

    private final WyHomeMapper wyHomeMapper;
    private final WyBalconyunithomeService wyBalconyunithomeService;
    private final WyHomeandtypeService wyHomeandtypeService;
    /**
     * 查询房间资料列表
     * 
     * @param wyHome 房间资料
     * @return 房间资料
     */
    @Override
    public List<WyHome> selectWyHomeList(WyHome wyHome)
    {
        return wyHomeMapper.selectWyHomeList(wyHome);
    }


    @Override
    public TableDataInfo selectInfo(WyHomeDTO wyHomeDTO) {
        PageDomain pageDomain = TableSupport.buildPageRequest();
        Page<WyBalconyunithome> page = Page.of(pageDomain.getPageNum(), pageDomain.getPageSize());
        Page<WyBalconyunithome> balconyUnitHomes = getBalconyUnitHomes(page, wyHomeDTO);
        TableDataInfo rspData = new TableDataInfo();
        rspData.setCode(HttpStatus.SUCCESS);
        rspData.setMsg("查询成功");
        rspData.setRows( balconyUnitHomes.getRecords().stream() .map(this::buildWyHomeDTO)
                .collect(Collectors.toList()));
        rspData.setTotal(
                balconyUnitHomes.getTotal()
        );
        return rspData;
    }


    @Override
    public WyHomeDTO getInfoById(Long id) {
        WyBalconyunithome wyBalconyunithome = Db.lambdaQuery(WyBalconyunithome.class)
                .eq(WyBalconyunithome::getId, id)
                .one();
        if (Objects.isNull(wyBalconyunithome)) {
            return null;
        }
        return buildWyHomeDTO(wyBalconyunithome);
    }

    @Override
    public boolean deleteBatchIds(List<Long> list) {
        List<Long> collect = Db.lambdaQuery(WyBalconyunithome.class)
                .in(WyBalconyunithome::getId, list)
                .list().stream().map(WyBalconyunithome::getHomeid)
                .collect(Collectors.toList());

        this.removeByIds(collect);
        return wyBalconyunithomeService.removeByIds(list);


    }

    @Override
    public boolean edit(WyHomeDTO wyHomeDTO) {
        WyHome wyHome = BeanUtil.copyProperties(wyHomeDTO, WyHome.class);
        this.updateById(wyHome);
        if (!wyHomeDTO.getHomeTypeIds().isEmpty()){
            List<Long> oldTypeIds = Db.lambdaQuery(WyHomeandtype.class)
                    .eq(WyHomeandtype::getHomeid, wyHomeDTO.getHomeId())
                    .list().stream().map(WyHomeandtype::getHometypeid).collect(Collectors.toList());
            List<Long> addTypeIds = wyHomeDTO.getHomeTypeIds().stream()
                    .filter(item -> !oldTypeIds.contains(item))
                    .collect(Collectors.toList());

            List<Long> delTypeIds = oldTypeIds.stream()
                    .filter(item -> !wyHomeDTO.getHomeTypeIds().contains(item))
                    .collect(Collectors.toList());

            if (!delTypeIds.isEmpty()) {
                wyHomeandtypeService.removeByIds(
                        Db.lambdaQuery(WyHomeandtype.class)
                                .eq(WyHomeandtype::getHomeid,wyHome.getHomeId())
                                .in(WyHomeandtype::getHometypeid,delTypeIds)
                                .list().stream().map(WyHomeandtype::getId).collect(Collectors.toList())
                );
            }
            List<WyHomeandtype> wyHomeandtypeList  = new ArrayList<>();
            addTypeIds.forEach(
                    item -> wyHomeandtypeList.add(
                            WyHomeandtype.builder()
                                    .homeid(wyHome.getHomeId())
                                    .hometypeid(item)
                                    .build()
                    )
            );
            wyHomeandtypeService.saveBatch(wyHomeandtypeList);
        }
       if (Db.lambdaQuery(WyBalconyunithome.class)
               .eq(WyBalconyunithome::getId,wyHomeDTO.getId())
               .one().equals(
                       WyBalconyunithome.builder()
                               .id(wyHomeDTO.getId())
                               .balconyid(wyHomeDTO.getBalconyid())
                               .unitid(wyHomeDTO.getUnitid())
                               .homeid(wyHomeDTO.getHomeId())
                               .build()
               )){
           return true;
       }else {
           wyBalconyunithomeService.removeById(wyHomeDTO.getId());
           return wyBalconyunithomeService.save(
                   WyBalconyunithome.builder()
                           .id(wyHomeDTO.getId())
                           .balconyid(wyHomeDTO.getBalconyid())
                           .unitid(wyHomeDTO.getUnitid())
                           .homeid(wyHomeDTO.getHomeId())
                           .build()
           );
       }
    }

    @Override
    public boolean insert(WyHomeDTO wyHomeDTO) {
        List<WyHomeDTO> list = Db.lambdaQuery(WyBalconyunithome.class)
                .eq(wyHomeDTO.getBalconyid() != null, WyBalconyunithome::getBalconyid, wyHomeDTO.getBalconyid())
                .eq(wyHomeDTO.getUnitid() != null, WyBalconyunithome::getUnitid, wyHomeDTO.getUnitid())
//                .in(WyBalconyunithome::getBalconyid, balconyIds)
                .isNotNull(WyBalconyunithome::getHomeid)
//                .page(page);
                .list().stream().map(this::buildWyHomeDTO).collect(Collectors.toList());

        if(list.stream().anyMatch(
                item ->  item.getCommunityId().equals(wyHomeDTO.getCommunityId()) &&
                        item.getBalconyid().equals(wyHomeDTO.getBalconyid()) &&
                        item.getUnitid().equals(wyHomeDTO.getUnitid()) &&
                        item.getHomeNumber().equals(wyHomeDTO.getHomeNumber())
        )){
            throw new RuntimeException("该小区楼座单元下已经存在该门牌号的房间，不允许添加！！！");
        }
        WyHome wyHome = BeanUtil.copyProperties(wyHomeDTO, WyHome.class);
        wyHome.setHomeLayserNumber(wyHomeDTO.getHomeNumber()/100);
        wyHome.setHomeLocation(Db.lambdaQuery(WyBalcony.class)
                .eq(WyBalcony::getBalconyId,wyHomeDTO.getBalconyid())
                .one().getBalconyName() + Db.lambdaQuery(WyUnit.class)
                .eq(WyUnit::getUnitId,wyHomeDTO.getUnitid())
                .one().getUnitName()+ wyHome.getHomeNumber() + "号");
        this.save(wyHome);
        if (!wyHomeDTO.getHomeTypeIds().isEmpty()) {
            List<WyHomeandtype> wyHomeandtypeList = new ArrayList<>();
            wyHomeDTO.getHomeTypeIds().forEach(
                    item -> wyHomeandtypeList.add(
                            WyHomeandtype.builder()
                                    .homeid(wyHome.getHomeId())
                                    .hometypeid(item)
                                    .build()
                    )
            );
            wyHomeandtypeService.saveBatch(wyHomeandtypeList);
        }
        return wyBalconyunithomeService.save(
                WyBalconyunithome.builder()
                        .homeid(wyHome.getHomeId())
                        .balconyid(wyHomeDTO.getBalconyid())
                        .unitid(wyHomeDTO.getUnitid())
                        .build()
        );
    }

    private List<Long> getBalconyIds(Long communityId) {
        return Db.lambdaQuery(WyBalcony.class)
                .eq(communityId != null, WyBalcony::getCommunityId, communityId)
                .list().stream().map(WyBalcony::getBalconyId).collect(Collectors.toList());
    }

    private Page<WyBalconyunithome> getBalconyUnitHomes(Page<WyBalconyunithome> page, WyHomeDTO wyHomeDTO) {
        return Db.lambdaQuery(WyBalconyunithome.class)
                .eq(wyHomeDTO.getBalconyid() != null, WyBalconyunithome::getBalconyid, wyHomeDTO.getBalconyid())
                .eq(wyHomeDTO.getUnitid() != null, WyBalconyunithome::getUnitid, wyHomeDTO.getUnitid())
                .isNotNull(WyBalconyunithome::getHomeid)
                .orderBy(true, false, WyBalconyunithome::getId)
                .page(page);
    }

    private WyHomeDTO buildWyHomeDTO(WyBalconyunithome item) {
        Long homeId = item.getHomeid();
        WyHome wyHome = Db.lambdaQuery(WyHome.class)
                .eq(WyHome::getHomeId, homeId)
                .one();
        WyBalcony wyBalcony = Db.lambdaQuery(WyBalcony.class)
                .eq(WyBalcony::getBalconyId, item.getBalconyid())
                .one();
        WyUnit wyUnit = Db.lambdaQuery(WyUnit.class)
                .eq(WyUnit::getUnitId, item.getUnitid())
                .one();

        return WyHomeDTO.builder()
                .id(item.getId())
                .homeId(homeId)
                .homeNumber(wyHome.getHomeNumber())
                .homeLayserNumber(wyHome.getHomeNumber()/100)
                .communityId(wyBalcony.getCommunityId())
                .area(wyHome.getArea())
                .balconyid(item.getBalconyid())
                .unitid(item.getUnitid())
                .homeRemark(wyHome.getHomeRemark())
                .ownerId(wyHome.getOwnerId())
                .usableArea(wyHome.getUsableArea())
                .warehouseArea(wyHome.getWarehouseArea())
                .homeLocation(wyBalcony.getBalconyName() + wyUnit.getUnitName() + wyHome.getHomeNumber() + "号")
                .homeTypeIds(Db.lambdaQuery(WyHomeandtype.class)
                        .eq(WyHomeandtype::getHomeid, homeId)
                        .list().stream().map(WyHomeandtype::getHometypeid).collect(Collectors.toList()))
                .build();
    }
}


